/**
*
* @author Anastasiya
*
*/

#pragma once
#include "ozawa.h"
#include "report.h"
#include "printing.h"
#include <string>
#include <ogdf/basic/Graph.h>
#include <ogdf/basic/Graph_d.h>

/**
* Class for traversal through input path (directory or file) and processing each graph file
*/
class InputProcessor{
public: // Creates processor for path <inputPath> in <testMode>. If <testMode> is true, then 
	// file processing is verbose, false = otherwise
	InputProcessor(const std::string inputPath, const bool testMode);
	~InputProcessor();
	// Executes procession of all files in input directory 
	void process();
	// Processes results if algorithm execution succeeded
	void processAlgorithmResult(const std::string inputFileName, 
		const ogdf::Graph* graph, const int deletedEngesCount, const ULONGLONG executionTime) const;
	// Processes results if algorithm execution failed
	void processAlgorithmError(const std::string inputFileName, const std::string errorDescription);
private:std::string inputPath;
		bool testMode; 
		int processedFileCount;
		int failedFileCount;
		ReportWriter* reportWriter;
		const Printer* printer;
		// Process single graph file
		void processGraph(const std::string fileName);
		// Writes graph to file
		static void writeGraph(const ogdf::Graph* resultGraph, const std::string fileName);
		// Traverses input directory and process each file (excepts <exclusionName>)
		void traverseDirectory (const std::string exclusionName);

		static const std::string REPORT_FILE_NAME;
		static const std::string ERROR_INPUT_PATH_NOT_EXISTS;
		static const std::string ERROR_READING_DIRECTORY;

};

class WriteReportHandler:public OzawaResultHandler{
public:WriteReportHandler(InputProcessor* processor);
	   void resultProcessionFunction(const std::string inputFileName, 
		   const ogdf::Graph* graph, const int deletedEngesCount, const ULONGLONG executionTime) const;
	   void errorProcessionFunction(const std::string inputFileName, const std::string errorDescription) const;
private: InputProcessor* processor;
};
